using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Ball : MonoBehaviour
{
    [SerializeField] private float normalMoveSpeed;
    [SerializeField] private float fastMoveSpeed;
    [SerializeField] private float slowMoveSpeed;
    [SerializeField] private int superAttackPower;

    private Vector2 originPos;
    private BuffController buffController;
    private float moveSpeed;
    private int attackPower;
    private Locomotion locomotion;

    public const int NORMAL_ATTACKPOWER = 1;

    private void Awake() {
        locomotion = GetComponent<Locomotion>();
        buffController = GetComponent<BuffController>();
    }

    private void Start() {
        originPos = transform.position;
        moveSpeed = normalMoveSpeed;
        attackPower = NORMAL_ATTACKPOWER;
        ResetBall();
    }

    private void OnEnable() {
        EventHandler.AddListener(Events.ResetGame, ResetBall);
        // EventHandler.AddListener(Events.NextLevel, ()=> rigidbody2D.velocity = Vector2.zero );
        EventHandler.AddListener(Events.NextLevel, ()=> locomotion.SetVelocity(Vector2.zero));
        EventHandler.AddListener<PropType, float>(Events.GetBuff, BuffAction);
    }
    
    private void OnDisable() {
        EventHandler.RemoveListener(Events.ResetGame);
        EventHandler.RemoveListener(Events.NextLevel);
        EventHandler.RemoveListener(Events.GetBuff);
    }

    private void ResetBall()
    {
        transform.position = originPos;
        Invoke(nameof(RandomLaunch), 1f);
    }

    private void FixedUpdate() {
        locomotion.SetVelocity(locomotion.GetCurrentVelocity().normalized * moveSpeed);
    }

    public void RandomLaunch()
    {
        locomotion.SetVelocity(new Vector2(Random.Range(-1f, 1f), -1f) * moveSpeed);
    }

    public Vector2 GetCurrentVelocity()
    {
        return locomotion.GetCurrentVelocity();
    }

    public void SetVelocity(Vector2 velocity){
        locomotion.SetVelocity(velocity);
    }

    public int GetCurrentAttackPower()
    {
        return attackPower;
    }

    private void BuffAction(PropType type, float duration)
    {
        bool hasBuff = buffController.isHasBuff(type);

        if(!hasBuff)
        {
            switch(type)
            {
                case PropType.Fast:
                    moveSpeed = fastMoveSpeed;
                    break;
                
                case PropType.Slow:
                    moveSpeed = slowMoveSpeed;
                    break;
                
                case PropType.Add_AttackPower:
                    attackPower = superAttackPower;
                    break;
            }
        }

        buffController.UpdateBuffState(type, duration);
        float realDuration = buffController.GetBuffTimeStampByType(type) - Time.time;
        TimeManager.Instance.GetTimer(realDuration, ()=>{CancelBuff(type);});
    }

    private void CancelBuff(PropType type)
    {
        bool isInBuffDuring = buffController.isInBuffDuring(type);

        if(isInBuffDuring)
            return;
        
        switch(type)
        {
            case PropType.Fast:
                moveSpeed = normalMoveSpeed;
                break;
            
            case PropType.Slow:
                moveSpeed = normalMoveSpeed;
                break;
            
            case PropType.Add_AttackPower:
                attackPower = NORMAL_ATTACKPOWER;
                break;
        }

        buffController.SubBuffByType(type);
    }
}
